//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<XStatic.cpp>
///	@path	~/src/gui/xgui/
///	@date	2008/10/30
///	@brief	.

#define _FULLAPI
#include "config/config.h"

#include "gui/IGuiForm.h"
#include "gui/xgui/XStatic.h"
#include "gui/composite/composition.h"
#include "gui/image/ImageResource.h"

namespace xeres {

	IMPL_IOBJECT_CLASS_DYNAMIC( XLabel );

	// XLabel
	XLabel::XLabel( void )
		: IGuiControl( Rect<int>() , true , true , true )
	{
	}

	// XLabel
	XLabel::XLabel( const WString& label , const Rect<int>& placement )
		: IGuiControl( placement , true , true , true )
	{
		m_label.SetString( label );
	}
	// ~XLabel
	XLabel::~XLabel( void )
	{
	}
	// SetText
	void XLabel::SetText( const WString& text )
	{
		m_label.SetString( text );
		
		// Notify set text.
		OnSetText();

		// Update.
		UpdateControl();
	}
	RefWeak<CTextStyle> XLabel::GetStyle( void )
	{
		return m_label.GetStyle();
	}
	// Draw
	void XLabel::Draw( Composition& composition )
	{
		Rect<int> rect( GetRect() );

		// Draw underlay stuffs, such as background.
		OnPreDrawText( composition , rect );

		// Draw text.
		m_label.DrawText( composition , rect , rect );

		// Draw overlay stuffs.
		OnPostDrawText( composition , rect );
	}
	// OnSetText
	void XLabel::OnSetText( void )
	{
	}
	// OnSetStyle
	void XLabel::OnSetStyle( void )
	{
	}
	// OnPreDrawText
	void XLabel::OnPreDrawText( Composition& composition , const Rect<int>& bound )
	{
		Gdiplus::SolidBrush brush( Gdiplus::Color(33,33,33) );
		composition.graphics().FillRectangle( &brush , bound.left() , bound.top() , bound.width() , bound.height() );
	}
	// OnPostDrawText
	void XLabel::OnPostDrawText( Composition& composition , const Rect<int>& bound )
	{
		using namespace Gdiplus;
		composition.graphics().DrawRectangle( &Pen( &SolidBrush(Color(255,200,200,200)) ) , toRect( bound ) );
	}
	// GetStyle
	
	IMPL_IOBJECT_CLASS_DYNAMIC( XTextBlock );

	// XTextBlock
	XTextBlock::XTextBlock( void )
		: IGuiControl( Rect<int>() , true , true , true )
	{
	}

	// XTextBlock
	XTextBlock::XTextBlock( const WString& label , const Rect<int>& placement )
		: IGuiControl( placement , true , true , true )
	{
		m_label.SetString( label );
		m_label.SetSize( GetSize() );
	}

	// ~XTextBlock
	XTextBlock::~XTextBlock( void )
	{
	}
	// SetSize
	bool XTextBlock::SetSize( const Pair<int>& size )
	{
		if( __super::SetSize( size ) )
		{
			m_label.SetSize( size );
			return true;
		}
		return false;
	}
	// SetText
	void XTextBlock::SetText( const WString& text )
	{
		m_label.SetString( text );
		
		// Notify set text.
		OnSetText();

		// Update.
		UpdateControl();
	}
	// GetStyle
	RefWeak<CTextStyle> XTextBlock::GetStyle( void )
	{
		return m_label.GetStyle();
	}
	// Draw
	void XTextBlock::Draw( Composition& composition )
	{
		Rect<int> rect( GetRect() );

		OnPreDrawText( composition , GetBound() );

		// Draw text.
		m_label.DrawText( composition , rect , GetBound() );

		OnPostDrawText( composition , GetBound() );
	}
	// OnSetText
	void XTextBlock::OnSetText( void )
	{
	}
	// OnSetStyle
	void XTextBlock::OnSetStyle( void )
	{
	}
	// OnPreDrawText
	void XTextBlock::OnPreDrawText( Composition& composition , const Rect<int>& bound )
	{
		Gdiplus::SolidBrush brush( Gdiplus::Color(33,33,33) );
		composition.graphics().FillRectangle( &brush , bound.left() , bound.top() , bound.width() , bound.height() );
	}
	// OnPostDrawText
	void XTextBlock::OnPostDrawText( Composition& composition , const Rect<int>& bound )
	{
		using namespace Gdiplus;
		composition.graphics().DrawRectangle( &Pen( &SolidBrush(Color(255,200,200,200)) ) , toRect( bound ) );
	}

		IMPL_IOBJECT_CLASS_DYNAMIC( XClickLabel );

	// XClickLabel
	XClickLabel::XClickLabel( void )
		: XLabel()
		, m_mouseEntered( 0 , 512 )
	{
		GetStyle()->m_horizontal = PlacementStyle::MIDDLE;
		GetStyle()->m_vertical = PlacementStyle::CENTER;
	}
	// XClickLabel
	XClickLabel::XClickLabel( const WString& label , const Rect<int>& placement )
		: XLabel( label , placement )
		, m_mouseEntered( 0 , 512 )
	{
		GetStyle()->m_horizontal = PlacementStyle::MIDDLE;
		GetStyle()->m_vertical = PlacementStyle::CENTER;
		OnSetText();
	}
	// ~XClickLabel
	XClickLabel::~XClickLabel( void )
	{
	}
	// SetOnClick
	void XClickLabel::SetOnClick( function<void()> call )
	{
		m_click = call;
	}
	// OnSetText
	void XClickLabel::OnSetText( void )
	{
	}
	// OnPreDrawText
	void XClickLabel::OnPreDrawText( Composition& composition , const Rect<int>& bound )
	{
	}
	// OnPostDrawText
	void XClickLabel::OnPostDrawText( Composition& composition , const Rect<int>& bound )
	{
		int alpha = (int)m_mouseEntered.Get();
		if( alpha > 0 )
		{
			using namespace Gdiplus;
			composition.graphics().DrawRectangle( &Pen( &SolidBrush( Color(alpha,200,200,200) ) ) , toRect( GetRect() ) );
		}
	}
	// OnKeyInput
	HandleInput XClickLabel::OnKeyInput( Updater& updater )
	{
		return INPUT_UNHANDLED;
	}
	// OnMouseInput
	HandleInput XClickLabel::OnMouseInput( Updater& updater )
	{
		if( updater.GetMouseInput().GetAction() == Input::ACTION_MOUSE_LB_CLICK )
		{
			if( m_click )
			{
				m_click();
			}
			return INPUT_HANDLED;
		}
		return INPUT_UNHANDLED;
	}
	// OnMouseEnter
	void XClickLabel::OnMouseEnter( Updater& updater , RefWeak<IGuiComp> last )
	{
		__super::OnMouseEnter( updater , last );
		// Make mouse enter effect.
		m_mouseEntered.Set( 255.f );
		if( !m_mouseEntered.IsEnded() )
		{
			m_parent->AddTickable( this );
		}
	}
	// OnMouseLeave
	void XClickLabel::OnMouseLeave( Updater& updater , RefWeak<IGuiComp> next )
	{
		__super::OnMouseLeave( updater , next );
		// Make mouse leave effect.
		m_mouseEntered.Set( 0.f );
		if( !m_mouseEntered.IsEnded() )
		{
			m_parent->AddTickable( this );
		}
	}
	// Tick
	void XClickLabel::Tick( Updater& updater , float dTime )
	{
		m_mouseEntered.Tick( dTime );
		if( m_mouseEntered.IsEnded() )
		{
			// Delete self from tickable list.
			m_parent->DelTickable( this );
		}
		UpdateControl();
	}
	
} // namespace xeres
